package com.yunpeng.dishes.biz.services.impl;

import com.alibaba.fastjson.JSONArray;
import com.alibaba.fastjson.JSONObject;
import com.yunpeng.common.constant.CommonConstantValues;
import com.yunpeng.dishes.biz.services.IDataCountProcessService;
import com.yunpeng.dishes.common.vo.NutrientsVO;
import com.yunpeng.dishes.common.vo.data.CurrentDayNutrientsView;
import com.yunpeng.dishes.common.vo.data.MealNutrientsView;
import com.yunpeng.dishes.common.vo.data.SuggestNutrientsView;
import com.yunpeng.dishes.dao.mapper.relation.IOrderDishesNutrientsMapper;
import com.yunpeng.dishes.dao.model.relation.OrderDishesNutrientsDO;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Service;

import javax.annotation.Resource;
import java.math.BigDecimal;
import java.util.*;

/**
 * DataCountProcessServiceImpl
 * 数据统计处理服务实现
 *
 * @author : Moore(hemw)
 * @date : 2020-05-13
 */
@Service
public class DataCountProcessServiceImpl implements IDataCountProcessService {


    /**
     * 日志对象
     */
    private static final Logger LOGGER = LoggerFactory.getLogger(DataCountProcessServiceImpl.class);

    @Value(value = "${suggest.calorie}")
    private BigDecimal suggestCalorie;

    @Resource
    private IOrderDishesNutrientsMapper orderDishesNutrientsMapper;

    @Override
    /**
     * 获取用户当天推荐营养数据
     *
     * @param userId cms用户id
     * @return
     */
    public SuggestNutrientsView getSuggestNutrientsView4User(Long userId) {
        List<OrderDishesNutrientsDO> orderDishesNutrientsDOList = orderDishesNutrientsMapper.queryLast30DaysListUser(userId);
        SuggestNutrientsView suggestNutrientsView = initRecommendNutrientsView();
        //最近无用餐数据，直接返回
        if (orderDishesNutrientsDOList == null || orderDishesNutrientsDOList.isEmpty()) {
            return suggestNutrientsView;
        }
        Map<String, MealNutrientsView> dateMealMap = new HashMap<>(16);
        Map<String, MealNutrientsView> currentDayMealMap = new HashMap<>(16);
        String now = CommonConstantValues.DAY_FORMAT.format(new Date());
        for (OrderDishesNutrientsDO orderDishesNutrientsDO : orderDishesNutrientsDOList) {
            String date = CommonConstantValues.DAY_FORMAT.format(orderDishesNutrientsDO.getCreateTime());
            //设置每餐营养数据
            MealNutrientsView mealNutrientsView = new MealNutrientsView();
            mealNutrientsView.setNutrients(new ArrayList<>());
            try {
                JSONObject snapshot = JSONObject.parseObject(orderDishesNutrientsDO.getDishesSnapshots());
                JSONArray nutrientsArray = snapshot.getJSONArray("nutrients");
                if (nutrientsArray != null || nutrientsArray.size() > 0) {
                    List<NutrientsVO> nutrients = nutrientsArray.toJavaList(NutrientsVO.class);
                    mealNutrientsView.setNutrients(nutrients);
                    mealNutrientsView.setCalorie(getCalories(mealNutrientsView));
                }
            } catch (Exception ex) {
                LOGGER.error("transfer snap shot error,", ex);
            }
            mealNutrientsView.setDate(date);
            mealNutrientsView.setMealType(orderDishesNutrientsDO.getMealType());
            String key = String.format("%s_%d", date, orderDishesNutrientsDO.getMealType());
            if (dateMealMap.containsKey(key)) {
                //同一天 同一餐合并
                MealNutrientsView existMealNutrientsView = dateMealMap.get(key);
                mealNutrientsView = margeMealNutrients(existMealNutrientsView, mealNutrientsView);
            }
            dateMealMap.put(key, mealNutrientsView);
            if (date.equalsIgnoreCase(now)) {
                currentDayMealMap.put(key, mealNutrientsView);
            }
        }
        BigDecimal calorie = BigDecimal.ZERO;
        for (Map.Entry<String, MealNutrientsView> currentDayMapEntry : currentDayMealMap.entrySet()) {
            MealNutrientsView mealNutrientsView = currentDayMapEntry.getValue();
            calorie = mealNutrientsView.getCalorie().add(calorie).setScale(2, BigDecimal.ROUND_HALF_UP);
        }
        suggestNutrientsView.getCurrentDayNutrientsView().setIntakeCalorie(calorie);
        suggestNutrientsView.getCurrentDayNutrientsView().setLackCalorie(suggestCalorie.subtract(calorie).setScale(2, BigDecimal.ROUND_HALF_UP));
        suggestNutrientsView.getCurrentDayNutrientsView().setMealNutrientsViews(new ArrayList<>(currentDayMealMap.values()));
        suggestNutrientsView.setMealNutrientsViews(new ArrayList<>(dateMealMap.values()));
        return suggestNutrientsView;
    }


    /**
     * 同一天 同一餐合并
     *
     * @param existMealNutrientsView
     * @param newMealNutrientsView
     * @return
     */
    private MealNutrientsView margeMealNutrients(MealNutrientsView existMealNutrientsView, MealNutrientsView newMealNutrientsView) {
        //新信息为空直接返回
        if (newMealNutrientsView.getNutrients() == null || newMealNutrientsView.getNutrients().isEmpty()) {
            return existMealNutrientsView;
        }
        //存在信息为空，直接设置
        if (existMealNutrientsView.getNutrients() == null || existMealNutrientsView.getNutrients().isEmpty()) {
            existMealNutrientsView.setNutrients(newMealNutrientsView.getNutrients());
            existMealNutrientsView.setCalorie(newMealNutrientsView.getCalorie());
            return existMealNutrientsView;
        }
        //都存在，相加
        BigDecimal calories = existMealNutrientsView.getCalorie();
        if (calories == null) {
            calories = newMealNutrientsView.getCalorie();
        } else {
            calories = calories.add(newMealNutrientsView.getCalorie()).setScale(2, BigDecimal.ROUND_HALF_UP);
        }
        List<NutrientsVO> newNutrientsList = new ArrayList<>();
        for (NutrientsVO item : existMealNutrientsView.getNutrients()) {
            for (NutrientsVO newItem : newMealNutrientsView.getNutrients()) {
                if (newItem.getCode().equalsIgnoreCase(item.getCode())) {
                    if (item.getNetContent() == null) {
                        item.setNetContent(newItem.getNetContent());
                    } else {
                        item.setNetContent(item.getNetContent().add(newItem.getNetContent()).setScale(2, BigDecimal.ROUND_HALF_UP));
                    }
                    break;
                }
            }
            newNutrientsList.add(item);
        }
        existMealNutrientsView.setNutrients(newNutrientsList);
        existMealNutrientsView.setCalorie(calories);
        return existMealNutrientsView;
    }

    /**
     * 获取卡路里
     *
     * @param mealNutrientsView
     * @return
     */
    private BigDecimal getCalories(MealNutrientsView mealNutrientsView) {
        NutrientsVO calories = null;
        for (NutrientsVO nutrient : mealNutrientsView.getNutrients()) {
            //热量
            if (nutrient.getCode().equalsIgnoreCase("1")) {
                calories = nutrient;
                break;
            }
        }
        if (calories != null) {
            return calories.getNetContent();
        }
        return BigDecimal.ZERO;
    }

    /**
     * 初始化默认的视图数据
     *
     * @return
     */
    private SuggestNutrientsView initRecommendNutrientsView() {
        CurrentDayNutrientsView currentDayNutrientsView = new CurrentDayNutrientsView();
        currentDayNutrientsView.setSuggestCalorie(suggestCalorie);
        currentDayNutrientsView.setLackCalorie(suggestCalorie);
        currentDayNutrientsView.setIntakeCalorie(BigDecimal.ZERO);
        currentDayNutrientsView.setMealNutrientsViews(new ArrayList<>());

        SuggestNutrientsView suggestNutrientsView = new SuggestNutrientsView();
        suggestNutrientsView.setCurrentDayNutrientsView(currentDayNutrientsView);
        suggestNutrientsView.setMealNutrientsViews(new ArrayList<>());

        return suggestNutrientsView;
    }
}
